package config;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Objects;
import java.util.Properties;

/**
 * 动态加载properties不好使，不知道啥原因
 * @author admin
 *
 */
public class WatchConfigTask {
	private static Properties properties = new Properties();
	private static WatchService watchService = null;
	private static String fileName = "config.properties";
	private static int num=0;
	private static InputStream inputStream = null;
	static {
		try {
			File config = new File(WatchConfigTask.class.getClassLoader().getResource(fileName).getPath());
			System.out.println("####"+config.getAbsolutePath());
			watchService = FileSystems.getDefault().newWatchService();
			//监听fileName所在目录下文件的修改、删除事件
			Paths.get(config.getParent()).register(watchService, StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE);
			inputStream = new FileInputStream(WatchConfigTask.class.getClassLoader().getResource(fileName).getPath());
			properties.load(inputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
		//启动一个线程监听内容变化，并重新载入配置
		Thread watchThread = new Thread(new Runnable() {
			@Override
			public void run() {
				while(true){
					try {
						WatchKey watchKey = watchService.take();
						for(WatchEvent<?> event : watchKey.pollEvents()){
							if(Objects.equals(event.context().toString(), fileName)){
								System.out.println("配置文件发生变化，重新载入。");
								Properties tmpProperties = new Properties();
								System.out.println("===="+tmpProperties.getClass().getName() + "@" + Integer.toHexString(tmpProperties.hashCode()));
								inputStream.close();
								inputStream = new FileInputStream(Thread.currentThread().getContextClassLoader().getResource("").getPath()+File.separator+fileName);
								tmpProperties.load(inputStream);
								properties = tmpProperties;
								num=1;
								System.out.println("===="+tmpProperties.getClass().getName() + "@" + Integer.toHexString(tmpProperties.hashCode()));
								break;
							}
						}
						watchKey.reset();
					} catch (InterruptedException | IOException e) {
						e.printStackTrace();
					}
					
				}
			}
		});
		watchThread.setDaemon(true);
		watchThread.start();
		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println("关闭监听任务");
					watchService.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}));
	}
	public static void main(String[] args) {
		int i=0;
		System.out.println("输出配置文件内容：");
		while(i<20){
			System.out.println(num+properties.getClass().getName() + "@" + Integer.toHexString(properties.hashCode()));
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			i++;
		}
	}
}
